package com.yf.exam.modules.user.book.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.qu.entity.Qu;
import com.yf.exam.modules.qu.service.QuService;
import com.yf.exam.modules.user.UserUtils;
import com.yf.exam.modules.user.book.dto.UserBookDTO;
import com.yf.exam.modules.user.book.entity.UserBook;
import com.yf.exam.modules.user.book.mapper.UserBookMapper;
import com.yf.exam.modules.user.book.service.UserBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-27 17:56
*/
@Service
public class UserBookServiceImpl extends ServiceImpl<UserBookMapper, UserBook> implements UserBookService {

    @Autowired
    private QuService quService;

    @Override
    public IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO) {

        //创建分页对象
        Page<UserBook> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());

        //查询条件
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        // 查找用户的当前错题（排除历史错题）
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId(true))
                .and(w -> w.eq(UserBook::getStatus, 0).or().isNull(UserBook::getStatus));

        UserBookDTO params = reqDTO.getParams();
        if(params!=null){
            if(!StringUtils.isEmpty(params.getTitle())){
                wrapper.lambda().like(UserBook::getTitle, params.getTitle());
            }

            if(!StringUtils.isEmpty(params.getExamId())){
                wrapper.lambda().eq(UserBook::getExamId, params.getExamId());
            }
        }

        //获得数据
        IPage<UserBook> page = this.page(query, wrapper);
        //转换结果
        IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>(){});
        return pageData;
     }

    @Override
    public IPage<UserBookDTO> pagingHistory(PagingReqDTO<UserBookDTO> reqDTO) {
        //创建分页对象
        Page<UserBook> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());

        //查询条件
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        // 查找用户的历史错题
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId(true))
                .eq(UserBook::getStatus, 1);

        UserBookDTO params = reqDTO.getParams();
        if(params!=null){
            if(!StringUtils.isEmpty(params.getTitle())){
                wrapper.lambda().like(UserBook::getTitle, params.getTitle());
            }

            if(!StringUtils.isEmpty(params.getExamId())){
                wrapper.lambda().eq(UserBook::getExamId, params.getExamId());
            }
        }

        //获得数据
        IPage<UserBook> page = this.page(query, wrapper);
        //转换结果
        IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>(){});
        return pageData;
    }

    @Override
    public IPage<UserBookDTO> pagingBySource(PagingReqDTO<UserBookDTO> reqDTO, Integer sourceType) {
        //创建分页对象
        Page<UserBook> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());

        //查询条件
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        // 查找用户的错题
        wrapper.lambda().eq(UserBook::getUserId, UserUtils.getUserId(true));
        
        // 根据来源类型筛选
        if (sourceType != null) {
            wrapper.lambda().eq(UserBook::getSourceType, sourceType);
        }

        UserBookDTO params = reqDTO.getParams();
        if(params!=null){
            if(!StringUtils.isEmpty(params.getTitle())){
                wrapper.lambda().like(UserBook::getTitle, params.getTitle());
            }

            if(!StringUtils.isEmpty(params.getExamId())){
                wrapper.lambda().eq(UserBook::getExamId, params.getExamId());
            }
        }

        //获得数据
        IPage<UserBook> page = this.page(query, wrapper);
        //转换结果
        IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>(){});
        return pageData;
    }



    @Override
    public void addBook(String examId, String quId) {
        // 默认来源类型为在线考试(0)
        addBookWithSource(examId, quId, 0);
    }
    
    @Override
    public void addBookWithSource(String examId, String quId, Integer sourceType) {
        // 问题
        Qu qu = quService.getById(quId);
        
        // 如果题目不存在，则不添加到错题本
        if (qu == null) {
            return;
        }
        
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .eq(UserBook::getExamId, examId)
                .eq(UserBook::getQuId, quId);

        //查找已有的错题信息
        UserBook book = this.getOne(wrapper, false);

        if (book == null) {
            book = new UserBook();
            book.setExamId(examId);
            book.setUserId(UserUtils.getUserId());
            book.setTitle(qu.getContent());
            book.setQuId(quId);
            book.setWrongCount(1);
            book.setSourceType(sourceType); // 设置来源类型
            Integer maxSort = this.findMaxSort(examId, UserUtils.getUserId());
            book.setSort(maxSort+1);

            this.save(book);
        } else {
            book.setWrongCount(book.getWrongCount()+1);
            this.updateById(book);
        }
    }

    @Override
    public String findNext(String examId, String quId) {


        Integer sort = 999999;

        if(!StringUtils.isEmpty(quId)){
            QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
            wrapper.lambda()
                    .eq(UserBook::getUserId, UserUtils.getUserId())
                    .eq(UserBook::getExamId, examId)
                    .eq(UserBook::getQuId, quId);
            wrapper.last(" ORDER BY `sort` DESC");

            UserBook last = this.getOne(wrapper, false);
            if(last!=null){
                sort = last.getSort();
            }
        }

        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .eq(UserBook::getExamId, examId)
                .lt(UserBook::getSort, sort);
        wrapper.last(" ORDER BY `sort` DESC");

        UserBook next = this.getOne(wrapper, false);
        if(next != null){
            return next.getQuId();
        }

        return null;
    }

    /**
     * 查找最大的排序
     * @param userId
     * @return
     */
    private Integer findMaxSort(String examId, String userId){

        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getExamId, examId)
                .eq(UserBook::getUserId, userId);
        wrapper.last(" ORDER BY `sort` DESC");

        UserBook book = this.getOne(wrapper, false);
        if(book == null){
            return 0;
        }
        return book.getSort();
    }

    @Override
    @Transactional
    public String startPractice(String examId, Integer orderType) {
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .and(w -> w.eq(UserBook::getStatus, 0).or().isNull(UserBook::getStatus)); // 查询当前错题或status为null的错题
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            wrapper.lambda().eq(UserBook::getExamId, examId);
        }
        
        UserBook firstBook = null;
        
        if (orderType == 0) {
            // 顺序：按sort升序
            wrapper.orderByAsc("sort");
            firstBook = this.getOne(wrapper, false);
        } else {
            // 乱序：获取所有题目后随机选择
            List<UserBook> allBooks = this.list(wrapper);
            if (!allBooks.isEmpty()) {
                // 使用Java随机数选择第一个题目
                Random random = new Random();
                firstBook = allBooks.get(random.nextInt(allBooks.size()));
            }
        }
        
        // 如果找到错题，为所有当前错题增加练习次数
        if (firstBook != null) {
            System.out.println("=== 开始练习，更新练习次数 ===");
            System.out.println("examId: " + examId + ", orderType: " + orderType);
            
            // 获取所有当前错题
            QueryWrapper<UserBook> allCurrentWrapper = new QueryWrapper<>();
            allCurrentWrapper.lambda()
                    .eq(UserBook::getUserId, UserUtils.getUserId())
                    .and(w -> w.eq(UserBook::getStatus, 0).or().isNull(UserBook::getStatus));
            
            // 如果examId不是'default'，则按examId过滤
            if (!"default".equals(examId)) {
                allCurrentWrapper.lambda().eq(UserBook::getExamId, examId);
            }
            
            List<UserBook> allCurrentBooks = this.list(allCurrentWrapper);
            System.out.println("找到 " + allCurrentBooks.size() + " 道当前错题，准备更新练习次数");
            
            // 批量更新练习次数
            for (UserBook book : allCurrentBooks) {
                book.setPracticeCount(book.getPracticeCount() != null ? book.getPracticeCount() + 1 : 1);
                System.out.println("更新错题ID: " + book.getId() + ", 练习次数: " + book.getPracticeCount());
            }
            
            // 批量更新
            this.updateBatchById(allCurrentBooks);
            System.out.println("批量更新练习次数完成");
        }
        
        return firstBook != null ? firstBook.getQuId() : null;
    }

    @Override
    public String getNextPracticeQu(String examId, String currentQuId, Integer orderType) {
        // 先获取当前题目的排序（不限制状态，因为题目可能已转为历史错题）
        QueryWrapper<UserBook> currentWrapper = new QueryWrapper<>();
        currentWrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .eq(UserBook::getQuId, currentQuId);
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            currentWrapper.lambda().eq(UserBook::getExamId, examId);
        }
        
        UserBook currentBook = this.getOne(currentWrapper, false);
        if (currentBook == null) {
            return null;
        }
        
        Integer currentSort = currentBook.getSort();
        
        // 查找下一个题目（不限制状态，因为题目可能已转为历史错题）
        QueryWrapper<UserBook> nextWrapper = new QueryWrapper<>();
        nextWrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId());
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            nextWrapper.lambda().eq(UserBook::getExamId, examId);
        }
        
        if (orderType == 0) {
            // 顺序：查找sort大于当前sort的最小值
            nextWrapper.lambda().gt(UserBook::getSort, currentSort);
            nextWrapper.orderByAsc("sort");
        } else {
            // 乱序：随机查找下一个题目（排除当前题目）
            nextWrapper.lambda().ne(UserBook::getQuId, currentQuId);
            nextWrapper.orderByAsc("RAND()");
        }
        
        UserBook nextBook = this.getOne(nextWrapper, false);
        return nextBook != null ? nextBook.getQuId() : null;
    }

    @Override
    @Transactional
    public Boolean submitPracticeAnswer(String examId, String quId, Boolean isCorrect) {
        System.out.println("=== 提交练习答案开始 ===");
        System.out.println("examId: " + examId + ", quId: " + quId + ", isCorrect: " + isCorrect);
        
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .eq(UserBook::getQuId, quId);
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            wrapper.lambda().eq(UserBook::getExamId, examId);
        }
        
        UserBook book = this.getOne(wrapper, false);
        if (book == null) {
            System.out.println("未找到错题记录");
            return false;
        }
        
        System.out.println("找到错题记录:");
        System.out.println("ID: " + book.getId());
        System.out.println("原始状态 - practiceCount: " + book.getPracticeCount() + 
                         ", correctCount: " + book.getCorrectCount() + 
                         ", wrongCount: " + book.getWrongCount() + 
                         ", status: " + book.getStatus());
        
        // 检查wrongCount是否为null
        if (book.getWrongCount() == null) {
            System.out.println("⚠️ 注意：wrongCount为null，将按0处理");
        }
        
        // 如果回答正确，增加正确次数
        if (isCorrect) {
            book.setCorrectCount(book.getCorrectCount() != null ? book.getCorrectCount() + 1 : 1);
        }
        
        System.out.println("更新后状态 - correctCount: " + book.getCorrectCount() + 
                         ", wrongCount: " + book.getWrongCount());
        
        // 检查是否应该转为历史错题：正确次数 > 错误次数
        Integer correctCount = book.getCorrectCount();
        Integer wrongCount = book.getWrongCount();
        
        // 处理null值
        if (correctCount == null) correctCount = 0;
        if (wrongCount == null) wrongCount = 0;
        
        boolean shouldMoveToHistory = correctCount > wrongCount;
        
        System.out.println("详细判断过程:");
        System.out.println("  correctCount: " + correctCount + " (原始: " + book.getCorrectCount() + ")");
        System.out.println("  wrongCount: " + wrongCount + " (原始: " + book.getWrongCount() + ")");
        System.out.println("  判断条件: " + correctCount + " > " + wrongCount + " = " + shouldMoveToHistory);
        System.out.println("是否应该转为历史错题: " + shouldMoveToHistory);
        
        if (shouldMoveToHistory) {
            book.setStatus(1); // 转为历史错题
            System.out.println("设置status为1（历史错题）");
        }
        
        System.out.println("准备更新数据库，最终状态: " + book.getStatus());
        
        // 使用LambdaUpdateWrapper进行更新，确保字段正确更新
        LambdaUpdateWrapper<UserBook> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserBook::getId, book.getId())
                   .set(UserBook::getCorrectCount, book.getCorrectCount())
                   .set(UserBook::getStatus, book.getStatus());
        
        boolean updateResult = this.update(updateWrapper);
        System.out.println("LambdaUpdateWrapper更新结果: " + updateResult);
        
        // 如果更新失败，尝试使用updateById
        if (!updateResult) {
            System.out.println("LambdaUpdateWrapper失败，尝试使用updateById");
            boolean updateResult2 = this.updateById(book);
            System.out.println("updateById结果: " + updateResult2);
        }
        
        // 验证更新结果
        UserBook updatedBook = this.getById(book.getId());
        if (updatedBook != null) {
            System.out.println("更新后验证 - status: " + updatedBook.getStatus() + 
                             ", correctCount: " + updatedBook.getCorrectCount());
            
            // 使用原生查询验证更新结果
            QueryWrapper<UserBook> verifyWrapper = new QueryWrapper<>();
            verifyWrapper.lambda().eq(UserBook::getId, book.getId());
            UserBook verifiedBook = this.getOne(verifyWrapper, false);
            if (verifiedBook != null) {
                System.out.println("原生查询验证 - status: " + verifiedBook.getStatus() + 
                                 ", correctCount: " + verifiedBook.getCorrectCount());
            }
        } else {
            System.out.println("无法获取更新后的记录");
        }
        
        // 额外测试：直接执行SQL更新
        if (shouldMoveToHistory) {
            System.out.println("尝试直接SQL更新status字段");
            try {
                // 方法1：使用原生SQL（暂时注释，因为execute方法可能不可用）
                // String sql = "UPDATE el_user_book SET status = ?, practice_count = ?, correct_count = ? WHERE id = ?";
                // int sqlResult = this.getBaseMapper().execute(sql, 1, book.getPracticeCount(), book.getCorrectCount(), book.getId());
                // System.out.println("原生SQL更新结果: " + sqlResult);
                
                // 方法2：使用LambdaUpdateWrapper
                LambdaUpdateWrapper<UserBook> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(UserBook::getId, book.getId())
                           .set(UserBook::getStatus, 1)
                           .set(UserBook::getPracticeCount, book.getPracticeCount())
                           .set(UserBook::getCorrectCount, book.getCorrectCount());
                boolean lambdaResult = this.update(lambdaUpdateWrapper);
                System.out.println("LambdaUpdateWrapper更新结果: " + lambdaResult);
                
                // 方法3：使用UpdateWrapper
                UpdateWrapper<UserBook> updateWrapper2 = new UpdateWrapper<>();
                updateWrapper2.eq("id", book.getId())
                             .set("status", 1)
                             .set("practice_count", book.getPracticeCount())
                             .set("correct_count", book.getCorrectCount());
                boolean updateResult3 = this.update(updateWrapper2);
                System.out.println("UpdateWrapper更新结果: " + updateResult3);
                
                // 再次验证
                UserBook finalBook = this.getById(book.getId());
                if (finalBook != null) {
                    System.out.println("所有更新方法后最终状态 - status: " + finalBook.getStatus());
                }
            } catch (Exception e) {
                System.out.println("直接SQL更新失败: " + e.getMessage());
                e.printStackTrace();
            }
        }
        
        System.out.println("=== 提交练习答案结束 ===");
        return shouldMoveToHistory;
    }

    @Override
    public Object getPracticeStats(String examId) {
        System.out.println("=== 获取练习统计开始 ===");
        System.out.println("examId: " + examId + ", userId: " + UserUtils.getUserId());
        
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId());
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            wrapper.lambda().eq(UserBook::getExamId, examId);
        }
        
        // 统计当前错题数量
        QueryWrapper<UserBook> currentWrapper = new QueryWrapper<>();
        currentWrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .and(w -> w.eq(UserBook::getStatus, 0).or().isNull(UserBook::getStatus));
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            currentWrapper.lambda().eq(UserBook::getExamId, examId);
        }
        long currentCount = this.count(currentWrapper);
        System.out.println("当前错题数量: " + currentCount);
        
        // 统计历史错题数量
        QueryWrapper<UserBook> historyWrapper = new QueryWrapper<>();
        historyWrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId())
                .eq(UserBook::getStatus, 1);
        
        // 如果examId不是'default'，则按examId过滤
        if (!"default".equals(examId)) {
            historyWrapper.lambda().eq(UserBook::getExamId, examId);
        }
        long historyCount = this.count(historyWrapper);
        System.out.println("历史错题数量: " + historyCount);
        
        // 统计总练习次数
        List<UserBook> allBooks = this.list(wrapper);
        System.out.println("总错题记录数: " + allBooks.size());
        
        // 统计总正确次数和总答题次数
        int totalCorrectCount = allBooks.stream()
                .mapToInt(book -> book.getCorrectCount() != null ? book.getCorrectCount() : 0)
                .sum();
        
        int totalAttemptCount = allBooks.stream()
                .mapToInt(book -> {
                    int correctCount = book.getCorrectCount() != null ? book.getCorrectCount() : 0;
                    int wrongCount = book.getWrongCount() != null ? book.getWrongCount() : 0;
                    return correctCount + wrongCount;
                })
                .sum();
        
        System.out.println("总正确次数: " + totalCorrectCount);
        System.out.println("总答题次数: " + totalAttemptCount);
        
        // 显示所有错题记录的详细状态
        System.out.println("所有错题记录状态:");
        for (UserBook book : allBooks) {
            System.out.println("ID: " + book.getId() + 
                             ", quId: " + book.getQuId() + 
                             ", status: " + book.getStatus() + 
                             ", practiceCount: " + book.getPracticeCount() + 
                             ", correctCount: " + book.getCorrectCount() + 
                             ", wrongCount: " + book.getWrongCount());
        }
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("currentCount", currentCount);
        stats.put("historyCount", historyCount);
        stats.put("totalCorrectCount", totalCorrectCount);
        stats.put("totalAttemptCount", totalAttemptCount);
        stats.put("accuracy", totalAttemptCount > 0 ? (double) totalCorrectCount / totalAttemptCount : 0.0);
        
        System.out.println("返回统计结果: " + stats);
        System.out.println("=== 获取练习统计结束 ===");
        
        return stats;
    }

    @Override
    @Transactional
    public boolean deleteUserBooks(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        
        // 查询这些ID是否都属于当前用户
        QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(UserBook::getUserId, UserUtils.getUserId(true))
                .in(UserBook::getId, ids);
        
        List<UserBook> userBooks = this.list(wrapper);
        
        // 如果查询到的数量与传入的ID数量不一致，说明有非法ID
        if (userBooks.size() != ids.size()) {
            System.out.println("删除失败：部分ID不属于当前用户");
            return false;
        }
        
        // 执行删除
        return this.remove(wrapper);
    }

}
